#include "utilities.h"
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
#include<string.h>

void read_control(float *x, float *y, float *sx, float *sy, float *px, float *py)
{
	FILE *fp;
	fp = fopen("/home/shiming1/InfoSphereStreams/letkf-spade/hysplit/data/CONTROL", "r");
	char str1[50];
	int info = 0;
	
	for (int i=0; i<17; i++)
		{
		(void)fgets(str1, 50, fp);
		}
	
	info = fscanf(fp, "%f", x);
	info = fscanf(fp, "%f", y);
	(void)fgets(str1, 50, fp);
	info = fscanf(fp, "%f", sx);
	info = fscanf(fp, "%f", sy);
	(void)fgets(str1, 50, fp);
	info = fscanf(fp, "%f", px);
	info = fscanf(fp, "%f", py);

	fclose(fp);
}

void get_time(int *yr, int *mo, int*dy, int *hr)	
{
	FILE *fp;
	fp = fopen("/home/shiming1/InfoSphereStreams/letkf-spade/hysplit/data/CONTROL", "r");
	int period = 0;
	int info = 0;
	char str1[150];	
	info = fscanf(fp, "%d", yr);
	info = fscanf(fp, "%d", mo);
	info = fscanf(fp, "%d", dy);
	info = fscanf(fp, "%d", hr);
	(void)fgets(str1, 20, fp);
	(void)fgets(str1, 20, fp);
	(void)fgets(str1, 20, fp);
	info = fscanf(fp, "%d", &period);
	adjust_time(period, yr, mo, dy, hr);
	fseek(fp, 0, SEEK_SET);
	
	fclose(fp);
}	
/*---------------------------------------------------*/
/*adjust_time forward the yr/mn/dy/hr by 'period' hours, and return*/
void adjust_time(int period, int *yr, int *mn, int *dy, int *hr)
{
	int tmpmn = *mn;
	
	if ((*hr + period) < 24)
		{
		*hr += period;
		}
	else
		{
		*dy = *dy + (*hr+period)/24;
		*hr = (*hr+period) % 24;
	
		switch(*mn)
		{
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			if (*dy<32)
			{
			}
			else
			{
			*mn = *mn + *dy/31;
			*dy = *dy % 31;
			}
			break;
	
		case 4:
		case 6:
		case 9:
		case 11:
			if (*dy<31)
			{
			}
			else
			{
			*mn = *mn + *dy/30;
			*dy = *dy % 30;
			}
			break;
		case 2:
			if ((*yr % 4) == 0)
				{
				if (*dy<30)
				{
				}
				else
				{
				*mn = *mn + *dy/30;
				*dy = *dy % 30;
				}
				}
			else
			{	
				if (*dy<29)
				{
				}
				else
				{
				*mn = *mn + *dy/29;
				*dy = *dy % 29;
				}
			}
			break;
		}//end of switch

		if (*mn != tmpmn)
		{
		if (*mn < 13)
			{
			}
		else
			{
			*yr = *yr + *mn/12;
			*mn = *mn % 12;
			//year
			if (*yr <= 99)
				{
				}
			else
				{
				*yr = *yr % 100;
				}	
			}	
		}
	
		}
}

/*--------------------------------------------*/
void write_parinit(int num_ensemble, int numpar, double *px_bar, float *px_tlat, float *px_tlon, float *px_zlvl, float *px_sigh, float *px_sigw, float *px_sigv, int16_t *px_page, int16_t *px_hdwp, int16_t *px_ptyp, int16_t *px_pgrd, double **pxen_mass, float **pxen_tlat, float **pxen_tlon, float **pxen_zlvl, float **pxen_sigh, float **pxen_sigw, float **pxen_sigv, int16_t **pxen_page, int16_t **pxen_hdwp, int16_t **pxen_ptyp, int16_t **pxen_pgrd)
{
	FILE *f2;

	int i, j, k;
	char strinit[150];
	char command[350];
	char bakcmd[350]="scp";
	int info = 0;
	int status1 = 0;
	char string1[100];
	char string2[100];
	char string3[100];
	char string4[100];
	int npar=0;
	int numpol = 0;
	int IYR = 0;
	int IMO = 0;
	int IDA = 0;
	int IHR = 0;

	f2 = fopen("/home/shiming1/InfoSphereStreams/letkf-spade/hysplit/data/tes1","r");
    (void)fgets(string1,100,f2);
	(void)fgets(string2,100,f2);
	(void)fgets(string3,100,f2);
	(void)fgets(string4,100,f2);

	info = fscanf(f2, "%d", &npar);
	info = fscanf(f2, "%d", &numpol);
	info = fscanf(f2, "%d", &IYR);
	info = fscanf(f2, "%d", &IMO);
	info = fscanf(f2, "%d", &IDA);
	info = fscanf(f2, "%d", &IHR);
	fclose(f2);
	
	for (j=0; j<num_ensemble; j++)
		{
		sprintf(strinit,"/home/shiming1/InfoSphereStreams/letkf-spade/hysplit/data/parinittxt%d",j);
		// write H_en[i][] to PARINIT for mass[]
		f2 = fopen(strinit, "w");
		fprintf(f2,"%s", string1);
		fprintf(f2,"%s", string2);
		fprintf(f2,"%s", string3);
		fprintf(f2,"%s", string4);

		fprintf(f2,"%12d",numpar);
		fprintf(f2,"%12d",numpol);
		fprintf(f2,"%12d",IYR);
		fprintf(f2,"%12d",IMO);
		fprintf(f2,"%12d",IDA);
		fprintf(f2,"%12d\n",IHR);

		k = 1;
		for(i=0; i<numpar; i++)
			{
			if (pxen_mass[j][i] != 0.00)
				{
				fprintf(f2,"%12.3E\n", pxen_mass[j][i]);
				fprintf(f2,"%12.3f",pxen_tlat[j][i]);
				fprintf(f2,"%12.3f",pxen_tlon[j][i]);
				fprintf(f2,"%12.3f",pxen_zlvl[j][i]);
				fprintf(f2,"%12.3f",pxen_sigh[j][i]);
				fprintf(f2,"%12.3f",pxen_sigw[j][i]);
				fprintf(f2,"%12.3f\n",pxen_sigv[j][i]);
				fprintf(f2,"%12d",pxen_page[j][i]);
				fprintf(f2,"%12d",pxen_hdwp[j][i]);
				fprintf(f2,"%12d",pxen_ptyp[j][i]);
				fprintf(f2,"%12d",pxen_pgrd[j][i]);
				fprintf(f2,"%12d\n", k++);
				}
			}
		fclose(f2);				
		// copy back to server
		strcpy(command, bakcmd);
		strcat(command, " ");
		strcat(command, strinit);
		strcat(command, " ITE366CS@130.85.94.246:/cygdrive/c/hysplit4/working/");
		if (fork())
		{
			wait(&status1);
		}
		else
		{
			info = system(command);
			exit(0);
		}			
			
		}
	//---------------------------------------
	f2 = fopen("/home/shiming1/InfoSphereStreams/letkf-spade/hysplit/data/parinittxt", "w");

	fprintf(f2,"%s", string1);
	fprintf(f2,"%s", string2);
	fprintf(f2,"%s", string3);
	fprintf(f2,"%s", string4);

	fprintf(f2,"%12d",numpar);
	fprintf(f2,"%12d",numpol);
	fprintf(f2,"%12d",IYR);
	fprintf(f2,"%12d",IMO);
	fprintf(f2,"%12d",IDA);
	fprintf(f2,"%12d\n",IHR);

	for(i=0; i<numpar; i++)
	{
		fprintf(f2,"%12.3E\n", px_bar[i]);
		fprintf(f2,"%12.3f", px_tlat[i]);
		fprintf(f2,"%12.3f", px_tlon[i]);
		fprintf(f2,"%12.3f", px_zlvl[i]);
		fprintf(f2,"%12.3f", px_sigh[i]);
		fprintf(f2,"%12.3f", px_sigw[i]);
		fprintf(f2,"%12.3f\n", px_sigv[i]);
		fprintf(f2,"%12d", px_page[i]);
		fprintf(f2,"%12d", px_hdwp[i]);
		fprintf(f2,"%12d", px_ptyp[i]);
		fprintf(f2,"%12d", px_pgrd[i]);
		fprintf(f2,"%12d\n",i+1);
	}
	fclose(f2);		
	
	if (fork())
	{
		wait(&status1);
	}
	else
	{
		info = system("scp /home/shiming1/InfoSphereStreams/letkf-spade/hysplit/data/parinittxt ITE366CS@130.85.94.246:/cygdrive/c/hysplit4/working/ > /dev/null");
		exit(0);
	}		
	
}

/*---------------------------------------------*/
void modify_control()
{
int status1;
FILE *fp;
fp = fopen("/home/shiming1/InfoSphereStreams/letkf-spade/hysplit/data/CONTROL","r+");
char str1[20];
int yr = 0;
int mn = 0;
int dy = 0;
int hr = 0;
int tmpmn = 0;
int period = 0;
int info = 0;
info = fscanf(fp, "%d", &yr);
info = fscanf(fp, "%d", &mn);
info = fscanf(fp, "%d", &dy);
info = fscanf(fp, "%d", &hr);
(void)fgets(str1, 20, fp);
(void)fgets(str1, 20, fp);
(void)fgets(str1, 20, fp);
info = fscanf(fp, "%d", &period);
	
tmpmn = mn;
fseek(fp, 0L, SEEK_SET);

if ((hr + period) < 24)
	{
	hr += period;
	fseek(fp, 9L, SEEK_SET);
	fprintf(fp, "%02d", hr);
	}
else
	{
	dy = dy + (hr+period)/24;
	hr = (hr+period) % 24;
	fseek(fp, 0L, SEEK_SET);
	fseek(fp, 9L, SEEK_SET);
	fprintf(fp, "%02d", hr);
	fseek(fp, 0L, SEEK_SET);
	
	switch(mn)
	{
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		if (dy<32)
		{
		fseek(fp, 6L, SEEK_SET);
		fprintf(fp, "%02d", dy);
		}
		else
		{
		mn = mn + dy/31;
		dy = dy % 31;
		fseek(fp, 6L, SEEK_SET);
		fprintf(fp, "%02d", dy);
		}
		break;
	
	case 4:
	case 6:
	case 9:
	case 11:
		if (dy<31)
		{
		fseek(fp, 6L, SEEK_SET);
		fprintf(fp, "%02d", dy);
		}
		else
		{
		mn = mn + dy/30;
		dy = dy % 30;
		fseek(fp, 6L, SEEK_SET);
		fprintf(fp, "%02d", dy);
		}
		break;
	case 2:
		if ((yr % 4) == 0)
			{
			if (dy<30)
			{
			fseek(fp, 6L, SEEK_SET);
			fprintf(fp, "%02d", dy);
			}
			else
			{
			mn = mn + dy/30;
			dy = dy % 30;
			fseek(fp, 6L, SEEK_SET);
			fprintf(fp, "%02d", dy);
			}
			}
		else
		{	
			if (dy<29)
			{
			fseek(fp, 6L, SEEK_SET);
			fprintf(fp, "%02d", dy);
			}
			else
			{
			mn = mn + dy/29;
			dy = dy % 29;
			fseek(fp, 6L, SEEK_SET);
			fprintf(fp, "%02d", dy);
			}
		}
		break;
	}//end of switch
	fseek(fp, 0L, SEEK_SET);
	if (mn != tmpmn)
	{
	if (mn < 13)
		{
		fseek(fp, 3L, SEEK_SET);
		fprintf(fp, "%02d", mn);
		}
	else
		{
		yr = yr + mn/12;
		mn = mn % 12;
		fseek(fp, 3L, SEEK_SET);
		fprintf(fp, "%02d", mn);
		fseek(fp, 0L, SEEK_SET);
		//year
		if (yr <= 99)
			{
			fseek(fp, 0L, SEEK_SET);
			fprintf(fp, "%02d", yr);
			}
		else
			{
			yr = yr % 100;
			fseek(fp, 0L, SEEK_SET);
			fprintf(fp, "%02d", yr);
			}	
		}	
	}
	
	}
fclose(fp);

	if (fork())// copy CONTROL back to server
	{
	wait(&status1);
	}
	else
	{
	info = system("scp /home/shiming1/InfoSphereStreams/letkf-spade/hysplit/data/CONTROL ITE366CS@130.85.94.246:/cygdrive/c/hysplit4/working/ > /dev/null");
	exit(0);
	}

}

/*-------------------------------------------------------*/
void statmain(int totalstep, int totstep, int ostep)
{
	int i;
	int info = 0;
	int status1 = 0;
	char str1[20];
	char str2[100];
	char cmd[200] = "ssh ITE366CS@130.85.94.246 'cd /cygdrive/c/hysplit4/working/; ./c2datem.exe";
	char cmdbak[200] = "ssh ITE366CS@130.85.94.246 'cd /cygdrive/c/hysplit4/working/; ./c2datem.exe";
	char command[300];
	if (fork())
		{
			wait(&status1);
		}
		else
		{
			info = system("ssh ITE366CS@130.85.94.246 'cd /cygdrive/c/hysplit4/working/; rm hysplittmp*'");
			exit(0);
		}
		
	for (i=0; i<totalstep; i++)
	{	strcpy(cmd, cmdbak);
		info = sprintf(str1, " -ibakdump%d", i+1);
		strcat(cmd, str1);
		info = sprintf(str2, " -ohysplittmp%d -mmeas-t1.txt -c1.0E+12 -xi -h0'", i+1);
		strcat(cmd, str2);
		if (fork())
		{
			wait(&status1);
		}
		else
		{
			info = system(cmd);
			exit(0);
		}
	}
	if (ostep < totstep)
	sprintf(command,"ssh ITE366CS@130.85.94.246 'cd /cygdrive/c/hysplit4/working/; cat hysplittmp* > dstat/ct1.txt; ./statmain.exe -at -ddcdump -fstations -rdstat; mv avg1_stations.txt avg1_exp%dA'",totalstep);
	else
	sprintf(command,"ssh ITE366CS@130.85.94.246 'cd /cygdrive/c/hysplit4/working/; cat hysplittmp* > dstat/ct1.txt; ./statmain.exe -at -ddcdump -fstations -rdstat; mv avg1_stations.txt avg1_exp%dB'",totalstep);
		if (fork())
		{
			wait(&status1);
		}
		else
		{
			info = system(command);
			exit(0);
		}
		//printf("The statistics result generated by 'statmain' is ready for view.\n");	
}
